home *** CD-ROM | disk | FTP | other *** search
- { _______________________________________________________________________
- / \
- | This unit provides most of the math. VectorSub, VectorCross, VectorNorm, |
- | and Calc_Normals where done by cono, so thanx for the help.. |
- \ _______________________________________________________________________ /
- }
- Unit MathUnit;
-
- Interface
-
- Uses VarUnit;
-
- procedure VectorSub(var a:vect3; b,c : vect3);
- procedure VectorCross(var a:vect3; b,c : vect3);
- procedure VectorNorm(var a:vect4; b : vect3);
- procedure Calc_Normals;
- procedure calcpolyZ;
- procedure Sort_Polyz;
- Procedure Rotate_Vertices;
- Procedure Rotate_Normals;
-
- Implementation
-
- procedure VectorSub(var a:vect3; b,c : vect3);
- begin
- a.x := b.x - c.x;
- a.y := b.y - c.y;
- a.z := b.z - c.z;
- end;
-
- procedure VectorCross(var a:vect3; b,c : vect3);
- begin
- a.x := b.y * c.z - b.z * c.y;
- a.y := b.z * c.x - b.x * c.z;
- a.z := b.x * c.y - b.y * c.x;
- end;
-
- procedure VectorNorm(var a:vect4; b : vect3);
- var vtemp : real;
- begin
- Vtemp := sqrt( b.x * b.x + b.y * b.y + b.z * b.z);
- a.x := b.x / Vtemp;
- a.y := b.y / Vtemp;
- a.z := b.z / Vtemp;
- end;
-
- procedure Calc_Normals;
- var v1,v2,v3 : vect3;
- vn : vect4;
- i,j,s : integer;
- vc : byte;
- cnt : longint;
-
- begin
- for i := 0 to vert do
- begin
- vertices[i].x := vertices[i].x div 4;
- vertices[i].y := vertices[i].y div 4;
- vertices[i].z := vertices[i].z div 4;
- end;
- for i := 0 to faces do
- begin
- VectorSub(V1, vertices[face[i,1]], vertices[face[i,0]]);
- VectorSub(V2, vertices[face[i,2]], vertices[face[i,0]]);
- VectorCross(V3,v1,v2);
- VectorNorm(vn,v3);
- normals[i] := vn;
- end;
- for j := 0 to faces do
- begin
- for vc := 0 to 2 do
- begin
- cnt := 0;
- for i := 0 to faces do
- begin
- if (face[i][0] = face[j][vc]) or
- (face[i][1] = face[j][vc]) or
- (face[i][2] = face[j][vc]) then
- begin
- vnormals[j].vn[vc].x := vnormals[j].vn[vc].x + round(normals[i].x*256);
- vnormals[j].vn[vc].y := vnormals[j].vn[vc].y + round(normals[i].y*256);
- vnormals[j].vn[vc].z := vnormals[j].vn[vc].z + round(normals[i].z*256);
- inc(cnt);
- end;
- end;
- vnormals[j].vn[vc].cnt := cnt;
- end;
- end;
- for j := 0 to faces do
- for vc := 0 to 2 do
- begin
- vnormals[j].vn[vc].x := vnormals[j].vn[vc].x*128;
- vnormals[j].vn[vc].y := vnormals[j].vn[vc].y*128;
- vnormals[j].vn[vc].z := vnormals[j].vn[vc].z*128;
- end;
- end;
-
- procedure calcpolyZ;
- var i : integer;
- begin
- for i := 0 to faces do polyz[i] := (z[face[i,0]]+z[face[i,1]]+z[face[i,2]]) div 3;
- end;
-
- procedure Sort_Polyz;
- procedure sort(l,r:integer);
- var i,j,x,y:integer;
- begin
- i:=l; j:=r; x:=Polyz[(l+r) div 2];
- repeat
- while PolyZ[i]<x do inc(i);
- while x<PolyZ[j] do dec(j);
- if i<=j then
- begin
- y:=PolyZ[i];
- PolyZ[i]:=PolyZ[j];
- PolyZ[j]:=y;
-
- y:=sortedz[i];
- sortedz[i]:=sortedz[j];
- sortedz[j]:=y;
-
- inc(i);
- dec(j);
- end;
- until i>j;
- if l<j then sort(l,j);
- if i<r then sort(i,r);
- end;
- begin
- calcpolyz;
- for i := 0 to faces do sortedz[i] := i;
- sort(0,faces);
- end;
-
- Procedure Rotate_Normals;
- Var Tx,Ty,Tz,Sx,Sy,Sz : Longint;
- Begin
- for i := 0 to faces do
- for j := 0 to 2 do begin
- TX := (CosTab[Ycnt] * vnormals[i].vn[j].x - SinTab[Ycnt] * vnormals[i].vn[j].z) div 256;
- TZ := (SinTab[Ycnt] * vnormals[i].vn[j].x + CosTab[Ycnt] * vnormals[i].vn[j].z) div 256;
- SX := (CosTab[Zcnt] * TX + SinTab[Zcnt] * vnormals[i].vn[j].y) div 256;
- TY := (CosTab[Zcnt] * vnormals[i].vn[j].y - SinTab[Zcnt] * TX) div 256;
- SZ := (CosTab[Xcnt] * TZ - SinTab[Xcnt] * TY) div 256;
- SY := (SinTab[Xcnt] * TZ + CosTab[Xcnt] * TY) div 256;
- vns[i].vn[j].x := SX;
- vns[i].vn[j].y := SY;
- vns[i].vn[j].z := SZ;
- if sz < 256*256 then FShow[i] := true else FShow[i] := false;
- end;
- for i := 0 to faces do if FShow[i] then
- for j := 0 to 2 do begin
- vns[i].vn[j].x := vns[i].vn[j].x div vnormals[i].vn[j].cnt;
- vns[i].vn[j].y := vns[i].vn[j].y div vnormals[i].vn[j].cnt;
- vns[i].vn[j].xt := vns[i].vn[j].x div 256+127;
- vns[i].vn[j].yt := vns[i].vn[j].y div 256+127;
- end;
- end;
-
- Procedure Rotate_Vertices;
- Var Tx,Ty,Tz : Longint;
- Sx,Sy,Sz : Longint;
- Begin
- for i := 0 to vert do begin
- Tx := (CosTab[Ycnt] * vertices[i].x - SinTab[Ycnt] * vertices[i].z) DIV 256;
- Tz := (SinTab[Ycnt] * vertices[i].x + CosTab[Ycnt] * vertices[i].z) DIV 256;
- Sx := (CosTab[Zcnt] * Tx + SinTab[Zcnt] * vertices[i].y) DIV 256;
- Ty := (CosTab[Zcnt] * vertices[i].y - SinTab[Zcnt] * Tx) DIV 256;
- Sz := (CosTab[Xcnt] * Tz - SinTab[Xcnt] * Ty) DIV 256;
- Sy := (SinTab[Xcnt] * Tz + CosTab[Xcnt] * Ty) DIV 256;
- X[i] := (256 * Sx div (Sz - Zpos) + Xpos);
- Y[i] := (256 * Sy div (Sz - Zpos) + Ypos);
- Z[i] := SZ;
- end;
- end;
-
- begin
- end.